<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
    <th:block th:include="include :: header('批量网站可访问性测试')" />
    <style>
        .test-container {
            max-width: 1200px;
            margin: 20px auto;
            padding: 20px;
        }
        .url-input-area {
            margin-bottom: 20px;
        }
        .url-textarea {
            width: 100%;
            height: 200px;
            font-family: monospace;
            font-size: 14px;
        }
        .test-controls {
            margin: 20px 0;
            text-align: center;
        }
        .results-container {
            margin-top: 20px;
        }
        .result-item {
            padding: 10px;
            margin: 5px 0;
            border-radius: 4px;
            border-left: 4px solid #ddd;
        }
        .result-success {
            background-color: #d4edda;
            border-left-color: #28a745;
        }
        .result-failed {
            background-color: #f8d7da;
            border-left-color: #dc3545;
        }
        .result-url {
            font-weight: bold;
            margin-bottom: 5px;
        }
        .result-details {
            font-size: 12px;
            color: #666;
        }
        .progress-container {
            margin: 20px 0;
            display: none;
        }
        .stats {
            display: flex;
            justify-content: space-around;
            margin: 20px 0;
            padding: 15px;
            background-color: #f8f9fa;
            border-radius: 4px;
        }
        .stat-item {
            text-align: center;
        }
        .stat-number {
            font-size: 24px;
            font-weight: bold;
            color: #007bff;
        }
        .export-controls {
            margin: 20px 0;
            text-align: center;
        }
    </style>
</head>
<body class="gray-bg">
    <div class="wrapper wrapper-content animated fadeInRight">
        <div class="test-container">
            <div class="ibox">
                <div class="ibox-title">
                    <h5>批量网站可访问性测试</h5>
                    <div class="ibox-tools">
                        <a class="collapse-link">
                            <i class="fa fa-chevron-up"></i>
                        </a>
                    </div>
                </div>
                <div class="ibox-content">
                    <div class="url-input-area">
                        <label for="urlList">输入要测试的URL列表（每行一个）：</label>
                        <textarea id="urlList" class="form-control url-textarea" placeholder="请输入URL，每行一个，例如：
http://www.baidu.com
https://www.google.com
http://10.10.94.90:22112/login
http://10.10.94.90:22115/pl/dist/index.html"></textarea>
                    </div>
                    
                    <div class="test-controls">
                        <button id="startTest" class="btn btn-primary btn-lg">
                            <i class="fa fa-play"></i> 开始批量测试
                        </button>
                        <button id="stopTest" class="btn btn-danger btn-lg" style="display: none;">
                            <i class="fa fa-stop"></i> 停止测试
                        </button>
                        <button id="clearResults" class="btn btn-warning btn-lg">
                            <i class="fa fa-trash"></i> 清空结果
                        </button>
                    </div>
                    
                    <div class="progress-container">
                        <div class="progress">
                            <div id="testProgress" class="progress-bar progress-bar-striped active" 
                                 role="progressbar" style="width: 0%">
                                <span id="progressText">0%</span>
                            </div>
                        </div>
                    </div>
                    
                    <div class="stats" id="statsContainer" style="display: none;">
                        <div class="stat-item">
                            <div class="stat-number" id="totalCount">0</div>
                            <div>总数</div>
                        </div>
                        <div class="stat-item">
                            <div class="stat-number" id="successCount" style="color: #28a745;">0</div>
                            <div>成功</div>
                        </div>
                        <div class="stat-item">
                            <div class="stat-number" id="failedCount" style="color: #dc3545;">0</div>
                            <div>失败</div>
                        </div>
                        <div class="stat-item">
                            <div class="stat-number" id="avgTime">0ms</div>
                            <div>平均耗时</div>
                        </div>
                    </div>
                    
                    <div class="export-controls" id="exportControls" style="display: none;">
                        <button id="exportJson" class="btn btn-info">
                            <i class="fa fa-download"></i> 导出JSON
                        </button>
                        <button id="exportCsv" class="btn btn-success">
                            <i class="fa fa-file-excel-o"></i> 导出CSV
                        </button>
                    </div>
                    
                    <div class="results-container">
                        <h4>测试结果</h4>
                        <div id="resultsArea"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <th:block th:include="include :: footer" />
    
    <script>
        let testResults = [];
        let isTestRunning = false;
        let testAbortController = null;

        $(document).ready(function() {
            $('#startTest').click(startBatchTest);
            $('#stopTest').click(stopTest);
            $('#clearResults').click(clearResults);
            $('#exportJson').click(exportJson);
            $('#exportCsv').click(exportCsv);
        });

        async function startBatchTest() {
            const urlText = $('#urlList').val().trim();
            if (!urlText) {
                $.modal.alertWarning('请输入要测试的URL列表');
                return;
            }

            const urls = urlText.split('\n')
                .map(url => url.trim())
                .filter(url => url.length > 0);

            if (urls.length === 0) {
                $.modal.alertWarning('请输入有效的URL');
                return;
            }

            isTestRunning = true;
            testAbortController = new AbortController();
            testResults = [];
            
            $('#startTest').hide();
            $('#stopTest').show();
            $('#progressContainer').show();
            $('#statsContainer').show();
            $('#exportControls').hide();
            $('#resultsArea').empty();

            updateStats(0, 0, 0, 0);
            updateProgress(0, urls.length);

            try {
                await runBatchTest(urls);
            } catch (error) {
                console.error('批量测试出错:', error);
                $.modal.alertError('批量测试出错: ' + error.message);
            } finally {
                isTestRunning = false;
                $('#startTest').show();
                $('#stopTest').hide();
                $('#progressContainer').hide();
                $('#exportControls').show();
            }
        }

        async function runBatchTest(urls) {
            const batchSize = 5; // 并发数量
            let completed = 0;
            let successCount = 0;
            let failedCount = 0;
            let totalTime = 0;

            for (let i = 0; i < urls.length; i += batchSize) {
                if (!isTestRunning) break;

                const batch = urls.slice(i, i + batchSize);
                const batchPromises = batch.map(url => testSingleUrl(url));
                
                const batchResults = await Promise.all(batchPromises);
                
                batchResults.forEach(result => {
                    testResults.push(result);
                    completed++;
                    
                    if (result.status) {
                        successCount++;
                        totalTime += result.time || 0;
                    } else {
                        failedCount++;
                    }
                    
                    displayResult(result);
                    updateProgress(completed, urls.length);
                    updateStats(urls.length, successCount, failedCount, 
                               successCount > 0 ? Math.round(totalTime / successCount) : 0);
                });

                // 短暂延迟避免过度请求
                await new Promise(resolve => setTimeout(resolve, 100));
            }
        }

        async function testSingleUrl(url) {
            try {
                const result = await testWithImageFirst(url, 10000);
                return { url, ...result };
            } catch (error) {
                return {
                    url,
                    status: false,
                    time: 0,
                    method: 'error',
                    note: error.message
                };
            }
        }

        // 复制webinfo.html中的testWithImageFirst函数
        function testWithImageFirst(url, timeout) {
            return new Promise((resolve, reject) => {
                if (!url.startsWith('http://') && !url.startsWith('https://')) {
                    url = 'http://' + url;
                }

                const img = new Image();
                const start = Date.now();
                let completed = false;
                
                const timeoutId = setTimeout(() => {
                    if (!completed) {
                        completed = true;
                        img.src = '';
                        reject(new Error('Image load timeout'));
                    }
                }, timeout);
                
                img.onload = () => {
                    if (!completed) {
                        completed = true;
                        clearTimeout(timeoutId);
                        resolve({
                            status: true,
                            time: Date.now() - start,
                            method: 'image',
                            note: 'Website accessible via image loading'
                        });
                    }
                };
                
                img.onerror = () => {
                    if (!completed) {
                        completed = true;
                        clearTimeout(timeoutId);
                        
                        fetch(url, { 
                            mode: 'no-cors',
                            method: 'GET',
                            signal: AbortSignal.timeout(timeout)
                        })
                        .then(() => {
                            resolve({
                                status: true,
                                time: Date.now() - start,
                                method: 'fetch_no_cors',
                                note: 'Website accessible via fetch no-cors'
                            });
                        })
                        .catch(() => {
                            resolve({
                                status: false,
                                time: Date.now() - start,
                                method: 'image_failed',
                                note: 'Website not accessible'
                            });
                        });
                    }
                };
                
                img.src = url + (url.includes('?') ? '&' : '?') + 't=' + Date.now();
            });
        }

        function displayResult(result) {
            const resultClass = result.status ? 'result-success' : 'result-failed';
            const statusIcon = result.status ? 
                '<i class="fa fa-check-circle" style="color: #28a745;"></i>' : 
                '<i class="fa fa-times-circle" style="color: #dc3545;"></i>';
            
            const methodNames = {
                'image': '图片加载',
                'fetch_no_cors': '无CORS模式',
                'image_failed': '图片失败',
                'error': '错误'
            };

            const html = `
                <div class="result-item ${resultClass}">
                    <div class="result-url">
                        ${statusIcon} ${result.url}
                    </div>
                    <div class="result-details">
                        方法: ${methodNames[result.method] || result.method} | 
                        耗时: ${result.time}ms | 
                        说明: ${result.note || '无'}
                    </div>
                </div>
            `;
            
            $('#resultsArea').append(html);
            $('#resultsArea').scrollTop($('#resultsArea')[0].scrollHeight);
        }

        function updateProgress(completed, total) {
            const percentage = Math.round((completed / total) * 100);
            $('#testProgress').css('width', percentage + '%');
            $('#progressText').text(`${completed}/${total} (${percentage}%)`);
        }

        function updateStats(total, success, failed, avgTime) {
            $('#totalCount').text(total);
            $('#successCount').text(success);
            $('#failedCount').text(failed);
            $('#avgTime').text(avgTime + 'ms');
        }

        function stopTest() {
            isTestRunning = false;
            if (testAbortController) {
                testAbortController.abort();
            }
        }

        function clearResults() {
            testResults = [];
            $('#resultsArea').empty();
            $('#statsContainer').hide();
            $('#exportControls').hide();
            updateStats(0, 0, 0, 0);
        }

        function exportJson() {
            const data = JSON.stringify(testResults, null, 2);
            downloadFile(data, 'batch-test-results.json', 'application/json');
        }

        function exportCsv() {
            const headers = ['URL', '状态', '耗时(ms)', '方法', '说明'];
            const rows = testResults.map(result => [
                result.url,
                result.status ? '成功' : '失败',
                result.time || 0,
                result.method || '',
                result.note || ''
            ]);
            
            const csvContent = [headers, ...rows]
                .map(row => row.map(field => `"${field}"`).join(','))
                .join('\n');
            
            downloadFile(csvContent, 'batch-test-results.csv', 'text/csv');
        }

        function downloadFile(content, filename, contentType) {
            const blob = new Blob([content], { type: contentType });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = filename;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }
    </script>
</body>
</html>